Bootstrap demo

Structures in C Language

Complete Guide with Examples and Best Practices

Table of Contents

1. Introduction to Structures

A structure in C is a user-defined data type that allows you to combine data items of different kinds. Structures are used to represent a record, making it easier to handle a group of logically related data items.

Note: Structures are fundamental for creating complex data types in C. They allow you to bundle together variables of different types under a single name.

For example, if you want to store information about a student, you might want to store their name (string), age (integer), and GPA (float). Instead of creating separate variables, you can create a structure that contains all this information.

2. Structure Definition and Declaration

2.1 Structure Syntax

Definition: The struct keyword is used to define a structure.

Syntax:

struct structure_name {
    data_type member1;
    data_type member2;
    // ... more members
};

Example:

// Define a structure for a student
struct Student {
    char name[50];
    int age;
    float gpa;
};

2.2 Structure Declaration

After defining a structure, you can declare variables of that structure type.

Example:

#include <stdio.h>

// Define the structure
struct Student {
    char name[50];
    int age;
    float gpa;
};

int main() {
    // Declare a structure variable
    struct Student student1;
    
    return 0;
}

2.3 Structure Initialization

Structure variables can be initialized at the time of declaration.

Example:

#include <stdio.h>

// Define the structure
struct Student {
    char name[50];
    int age;
    float gpa;
};

int main() {
    // Initialize a structure variable
    struct Student student1 = {"John Doe", 20, 3.8};
    
    return 0;
}

3. Accessing Structure Members

Structure members are accessed using the dot (.) operator.

Example:

#include <stdio.h>
#include <string.h>

// Define the structure
struct Student {
    char name[50];
    int age;
    float gpa;
};

int main() {
    // Declare and initialize a structure variable
    struct Student student1;
    
    // Accessing and assigning values to structure members
    strcpy(student1.name, "John Doe");
    student1.age = 20;
    student1.gpa = 3.8;
    
    // Accessing and printing structure members
    printf("Name: %s\n", student1.name);
    printf("Age: %d\n", student1.age);
    printf("GPA: %.2f\n", student1.gpa);
    
    return 0;
}

Output:

Name: John Doe
Age: 20
GPA: 3.80

4. Structure Operations

4.1 Structure Assignment

You can assign one structure variable to another of the same type.

Example:

#include <stdio.h>
#include <string.h>

struct Student {
    char name[50];
    int age;
    float gpa;
};

int main() {
    struct Student student1, student2;
    
    strcpy(student1.name, "John Doe");
    student1.age = 20;
    student1.gpa = 3.8;
    
    // Assign student1 to student2
    student2 = student1;
    
    printf("Student2 Name: %s\n", student2.name);
    printf("Student2 Age: %d\n", student2.age);
    printf("Student2 GPA: %.2f\n", student2.gpa);
    
    return 0;
}

4.2 Arrays of Structures

You can create arrays of structures to store multiple records.

Example:

#include <stdio.h>
#include <string.h>

struct Student {
    char name[50];
    int age;
    float gpa;
};

int main() {
    // Create an array of 3 students
    struct Student students[3];
    int i;
    
    // Input data for 3 students
    for(i = 0; i < 3; i++) {
        printf("Enter name, age, and GPA for student %d: ", i+1);
        scanf("%s %d %f", students[i].name, &students[i].age, &students[i].gpa);
    }
    
    // Display all students
    printf("\nStudent Information:\n");
    for(i = 0; i < 3; i++) {
        printf("Name: %s, Age: %d, GPA: %.2f\n", students[i].name, students[i].age, students[i].gpa);
    }
    
    return 0;
}

4.3 Nested Structures

A structure can contain another structure as its member.

Example:

#include <stdio.h>
#include <string.h>

// Define a structure for Address
struct Address {
    char street[50];
    char city[50];
    int zip;
};

// Define a structure for Student that contains Address
struct Student {
    char name[50];
    int age;
    float gpa;
    struct Address address; // Nested structure
};

int main() {
    struct Student student1;
    
    strcpy(student1.name, "John Doe");
    student1.age = 20;
    student1.gpa = 3.8;
    
    strcpy(student1.address.street, "123 Main St");
    strcpy(student1.address.city, "New York");
    student1.address.zip = 10001;
    
    printf("Name: %s\n", student1.name);
    printf("Address: %s, %s, %d\n", student1.address.street, student1.address.city, student1.address.zip);
    
    return 0;
}

5. Pointers to Structures

You can create pointers to structures and access members using the arrow (->) operator.

Example:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Student {
    char name[50];
    int age;
    float gpa;
};

int main() {
    struct Student student1;
    struct Student *ptr;
    
    ptr = &student1; // Pointer to student1
    
    // Accessing structure members using pointer
    strcpy(ptr->name, "John Doe");
    ptr->age = 20;
    ptr->gpa = 3.8;
    
    printf("Name: %s\n", ptr->name);
    printf("Age: %d\n", ptr->age);
    printf("GPA: %.2f\n", ptr->gpa);
    
    return 0;
}

6. Structures and Functions

Structures can be passed to functions by value or by reference.

Example:

#include <stdio.h>
#include <string.h>

struct Student {
    char name[50];
    int age;
    float gpa;
};

// Function to display student information (pass by value)
void displayStudent(struct Student s) {
    printf("Name: %s\n", s.name);
    printf("Age: %d\n", s.age);
    printf("GPA: %.2f\n", s.gpa);
}

// Function to update student GPA (pass by reference)
void updateGPA(struct Student *s, float newGPA) {
    s->gpa = newGPA;
}

int main() {
    struct Student student1;
    
    strcpy(student1.name, "John Doe");
    student1.age = 20;
    student1.gpa = 3.5;
    
    printf("Original GPA: %.2f\n", student1.gpa);
    updateGPA(&student1, 3.8); // Pass by reference
    printf("Updated GPA: %.2f\n", student1.gpa);
    
    displayStudent(student1); // Pass by value
    
    return 0;
}

7. typedef with Structures

The typedef keyword allows you to create an alias for a structure, making it easier to use.

Example:

#include <stdio.h>
#include <string.h>

// Using typedef to create an alias
typedef struct {
    char name[50];
    int age;
    float gpa;
} Student;

int main() {
    // Now we can use Student instead of struct Student
    Student student1;
    
    strcpy(student1.name, "John Doe");
    student1.age = 20;
    student1.gpa = 3.8;
    
    printf("Name: %s\n", student1.name);
    printf("Age: %d\n", student1.age);
    printf("GPA: %.2f\n", student1.gpa);
    
    return 0;
}

Note: Using typedef with structures makes the code cleaner and easier to read, as you don't have to use the struct keyword every time you declare a variable.

8. Best Practices

  • Use meaningful names for structures and their members
  • Initialize structure variables before using them
  • Use typedef to make structure declarations cleaner
  • Pass structures by reference when you need to modify them in functions
  • Pass structures by value when you don't need to modify them (for small structures)
  • Comment your structures to explain the purpose of each member
  • Use arrays of structures for managing collections of related data

9. Common Mistakes

1. Forgetting to use the struct keyword (without typedef)

struct Student {
    char name[50];
    int age;
};

// Wrong: Forgetting struct keyword
Student s1;

// Correct
struct Student s1;

2. Comparing structures directly

struct Point {
    int x;
    int y;
};

struct Point p1 = {1, 2};
struct Point p2 = {1, 2};

// Wrong: Cannot compare structures directly
if (p1 == p2) {
    // ...
}

// Correct: Compare individual members
if (p1.x == p2.x && p1.y == p2.y) {
    // ...
}

3. Using assignment instead of strcpy for strings

struct Student {
    char name[50];
    int age;
};

struct Student s1;

// Wrong: Cannot assign strings directly
s1.name = "John Doe";

// Correct: Use strcpy
strcpy(s1.name, "John Doe");

10. Real-world Examples

Example 1: Student Database System

#include <stdio.h>
#include <string.h>

typedef struct {
    int id;
    char name[50];
    float grades[5];
    float average;
} Student;

void calculateAverage(Student *s) {
    float sum = 0;
    for(int i = 0; i < 5; i++) {
        sum += s->grades[i];
    }
    s->average = sum / 5;
}

int main() {
    Student students[3];
    int i, j;
    
    // Input student data
    for(i = 0; i < 3; i++) {
        printf("Enter student %d ID: ", i+1);
        scanf("%d", &students[i].id);
        getchar(); // Clear input buffer
    
        printf("Enter student %d name: ", i+1);
        fgets(students[i].name, 50, stdin);
        students[i].name[strcspn(students[i].name, "\n")] = 0; // Remove newline
    
        printf("Enter 5 grades for student %d: ", i+1);
        for(j = 0; j < 5; j++) {
            scanf("%f", &students[i].grades[j]);
        }
    
        calculateAverage(&students[i]);
    }
    
    // Display student data
    printf("\nStudent Records:\n");
    for(i = 0; i < 3; i++) {
        printf("ID: %d, Name: %s, Average: %.2f\n", students[i].id, students[i].name, students[i].average);
    }
    
    return 0;
}

Example 2: Library Book Management

#include <stdio.h>
#include <string.h>

typedef struct {
    char title[100];
    char author[50];
    int year;
    int pages;
    float price;
} Book;

void displayBook(Book b) {
    printf("Title: %s\n", b.title);
    printf("Author: %s\n", b.author);
    printf("Year: %d\n", b.year);
    printf("Pages: %d\n", b.pages);
    printf("Price: $%.2f\n", b.price);
    printf("----------------------------\n");
}

int main() {
    Book library[3] = {
        {"The C Programming Language", "Kernighan and Ritchie", 1978, 272, 45.99},
        {"Clean Code: A Handbook of Agile Software Craftsmanship", "Robert C. Martin", 2008, 464, 37.50},
        {"Introduction to Algorithms", "Cormen, Leiserson, Rivest, Stein", 1990, 1312, 89.75}
    };
    
    printf("Library Catalog:\n");
    printf("----------------------------\n");
    
    for(int i = 0; i < 3; i++) {
        displayBook(library[i]);
    }
    
    return 0;
}